package org.example.mock;

import lombok.extern.slf4j.Slf4j;
import java.sql.*;
import java.util.*;

/**
 * 用于生成 MovieInfoCombined 模拟数据并插入数据库的工具类
 * 适配 movie_info_combined 表结构，基于真实语言和受众分类生成数据
 */
@Slf4j
public class MovieInfoCombinedGenerator {
    private static final String DB_URL = "jdbc:mysql://192.168.10.102/changchengfilm?requireSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "000000";
    private static final int BATCH_SIZE = 100;
    private static final List<MovieInfoCombinedData> DATA_LIST = new ArrayList<>();
    private static int currentId = 1;

    // 电影名称与元数据映射
    private static final Map<String, MovieMetadata> MOVIE_METADATA = new HashMap<>();

    // 语言映射表：国家/地区 -> 语言
    private static final Map<String, String> REGION_LANGUAGE_MAP;

    // 受众分类映射表
    private static final Map<String, String> GENRE_AUDIENCE_MAP;

    // 要处理的 50 部电影名称
    private static final String[] MOVIE_NAMES = {
            "肖申克的救赎", "教父", "黑暗骑士", "泰坦尼克号", "复仇者联盟4：终局之战",
            "星球大战：原力觉醒", "阿凡达", "蜘蛛侠：英雄远征", "侏罗纪世界", "黑豹",
            "哈利波特与混血王子", "冰雪奇缘2", "钢铁侠3", "美国队长3", "玩具总动员4",
            "速度与激情7", "奇异博士", "银河护卫队", "雷神3：诸神黄昏", "侏罗纪公园",
            "怪物史莱克2", "超人总动员", "海底总动员", "狮子王", "指环王：王者归来",
            "加勒比海盗", "蜘蛛侠：英雄归来", "蝙蝠侠：黑暗骑士崛起", "星球大战外传：侠盗一号", "爱丽丝梦游仙境",
            "哈利波特与死亡圣器（下）", "星球大战：最后的绝地武士", "速度与激情8", "黑豹2", "毒液：致命守护者",
            "蚁人2：黄蜂女现身", "美国队长2", "雷神2：黑暗世界", "钢铁侠2", "哈利波特与火焰杯",
            "变形金刚", "独立日", "侏罗纪世界2", "蜘蛛侠3", "哈利波特与凤凰社",
            "哪吒之魔童降世", "流浪地球2", "满江红", "长津湖", "你好，李焕英",
            "唐人街探案3", "美人鱼", "我不是药神", "红海行动", "战狼2",
            "封神第一部", "独行月球", "悬崖之上", "送你一朵小红花", "少年的你",
            "我和我的祖国", "八佰", "白蛇：缘起", "误杀", "刺杀小说家"
    };

    static {
        // 初始化语言映射表
        Map<String, String> tempLanguageMap = new HashMap<>();
        tempLanguageMap.put("美国", "英语");
        tempLanguageMap.put("中国", "汉语");
        tempLanguageMap.put("日本", "日语");
        tempLanguageMap.put("韩国", "韩语");
        tempLanguageMap.put("法国", "法语");
        tempLanguageMap.put("西班牙", "西班牙语");
        tempLanguageMap.put("英国", "英语");
        tempLanguageMap.put("德国", "德语");
        tempLanguageMap.put("新西兰", "英语");
        REGION_LANGUAGE_MAP = Collections.unmodifiableMap(tempLanguageMap);

        // 初始化受众映射表
        Map<String, String> tempAudienceMap = new HashMap<>();
        tempAudienceMap.put("科幻", "青少年,成人");
        tempAudienceMap.put("动作", "青少年,成人");
        tempAudienceMap.put("动画", "全年龄段,家庭观众");
        tempAudienceMap.put("儿童", "全年龄段,儿童");
        tempAudienceMap.put("喜剧", "全年龄段");
        tempAudienceMap.put("剧情", "成人");
        tempAudienceMap.put("文艺", "成人,文艺片观众");
        tempAudienceMap.put("悬疑", "成人,悬疑爱好者");
        tempAudienceMap.put("历史", "成人,历史爱好者");
        tempAudienceMap.put("战争", "成人,军事爱好者");
        tempAudienceMap.put("奇幻", "青少年,奇幻爱好者");
        tempAudienceMap.put("冒险", "青少年,冒险爱好者");
        tempAudienceMap.put("犯罪", "成人,犯罪片爱好者");
        GENRE_AUDIENCE_MAP = Collections.unmodifiableMap(tempAudienceMap);

        // 初始化电影元数据
        initMovieMetadata();
    }

    public static void main(String[] args) {
        log.info("开始生成 MovieInfoCombined 模拟数据并插入数据库");

        try {
            int count = MOVIE_NAMES.length;
            insertDataToDatabase(generateData(count));
            log.info("数据插入完成，共插入 {} 条记录", count);
        } catch (SQLException e) {
            log.error("数据库操作异常", e);
        } catch (Exception e) {
            log.error("发生未知异常", e);
        }
    }

    private static List<MovieInfoCombinedData> generateData(int count) {
        List<MovieInfoCombinedData> dataList = new ArrayList<>();

        for (String movieName : MOVIE_NAMES) {
            if (dataList.size() >= count) break;

            MovieMetadata meta = MOVIE_METADATA.get(movieName);
            if (meta == null) {
                log.warn("电影【{}】元数据缺失，跳过生成", movieName);
                continue;
            }

            MovieInfoCombinedData data = new MovieInfoCombinedData();
            data.setMovieId(currentId++);
            data.setMovieName(movieName);
            data.setOriginalLanguage(REGION_LANGUAGE_MAP.getOrDefault(meta.country, "英语"));
            data.setSubtitleLanguages(generateSubtitles(meta.country));
            data.setDubbedLanguages(generateDubbedLanguages(meta.country));
            data.setTargetAudience(determinePrimaryAudience(meta.genre));
            data.setSecondaryAudience(determineSecondaryAudience(meta.genre));

            dataList.add(data);
            DATA_LIST.add(data);
        }

        return dataList;
    }

    private static String generateSubtitles(String country) {
        Set<String> languages = new LinkedHashSet<>();
        languages.add("英语");

        String regionLang = REGION_LANGUAGE_MAP.get(country);
        if (regionLang != null && !regionLang.equals("英语")) {
            languages.add(regionLang);
        }

        if (!country.equals("中国")) languages.add("汉语");
        if (!country.equals("日本")) languages.add("日语");
        if (!country.equals("韩国")) languages.add("韩语");

        return String.join(",", languages);
    }

    private static String generateDubbedLanguages(String country) {
        Set<String> languages = new LinkedHashSet<>();
        String originalLang = REGION_LANGUAGE_MAP.getOrDefault(country, "英语");
        languages.add(originalLang);

        if (!originalLang.equals("英语")) languages.add("英语");
        if (!originalLang.equals("汉语") && !country.equals("中国")) languages.add("汉语");

        return String.join(",", languages);
    }

    private static String determinePrimaryAudience(String genre) {
        for (Map.Entry<String, String> entry : GENRE_AUDIENCE_MAP.entrySet()) {
            if (genre.contains(entry.getKey())) {
                String[] audiences = entry.getValue().split(",");
                return audiences[0];
            }
        }
        return "成人";
    }

    private static String determineSecondaryAudience(String genre) {
        for (Map.Entry<String, String> entry : GENRE_AUDIENCE_MAP.entrySet()) {
            if (genre.contains(entry.getKey())) {
                String[] audiences = entry.getValue().split(",");
                if (audiences.length > 1) {
                    return String.join(",", Arrays.copyOfRange(audiences, 1, audiences.length));
                }
            }
        }
        return "影迷群体";
    }

    private static void initMovieMetadata() {
        // 美国电影
        addMovieMetadata("肖申克的救赎", "美国", "剧情,犯罪");
        addMovieMetadata("教父", "美国", "剧情,犯罪");
        addMovieMetadata("黑暗骑士", "美国", "动作,犯罪,科幻");
        addMovieMetadata("泰坦尼克号", "美国", "剧情,爱情");
        addMovieMetadata("复仇者联盟4：终局之战", "美国", "动作,科幻,冒险");
        addMovieMetadata("星球大战：原力觉醒", "美国", "动作,科幻,冒险");
        addMovieMetadata("阿凡达", "美国", "动作,科幻,冒险");
        addMovieMetadata("蜘蛛侠：英雄远征", "美国", "动作,科幻,冒险");
        addMovieMetadata("侏罗纪世界", "美国", "动作,科幻,冒险");
        addMovieMetadata("黑豹", "美国", "动作,科幻,冒险");
        addMovieMetadata("哈利波特与混血王子", "美国", "奇幻,冒险");
        addMovieMetadata("冰雪奇缘2", "美国", "动画,奇幻,冒险");
        addMovieMetadata("钢铁侠3", "美国", "动作,科幻,冒险");
        addMovieMetadata("美国队长3", "美国", "动作,科幻,冒险");
        addMovieMetadata("玩具总动员4", "美国", "动画,喜剧,冒险");
        addMovieMetadata("速度与激情7", "美国", "动作,犯罪,冒险");
        addMovieMetadata("奇异博士", "美国", "动作,科幻,奇幻");
        addMovieMetadata("银河护卫队", "美国", "动作,科幻,冒险");
        addMovieMetadata("雷神3：诸神黄昏", "美国", "动作,科幻,奇幻");
        addMovieMetadata("侏罗纪公园", "美国", "动作,科幻,冒险");
        addMovieMetadata("怪物史莱克2", "美国", "动画,喜剧,奇幻");
        addMovieMetadata("超人总动员", "美国", "动画,动作,科幻");
        addMovieMetadata("海底总动员", "美国", "动画,冒险,家庭");
        addMovieMetadata("狮子王", "美国", "动画,冒险,歌舞");
        addMovieMetadata("指环王：王者归来", "美国", "动作,奇幻,冒险");
        addMovieMetadata("加勒比海盗", "美国", "动作,奇幻,冒险");
        addMovieMetadata("蜘蛛侠：英雄归来", "美国", "动作,科幻,冒险");
        addMovieMetadata("蝙蝠侠：黑暗骑士崛起", "美国", "动作,犯罪,科幻");
        addMovieMetadata("星球大战外传：侠盗一号", "美国", "动作,科幻,冒险");
        addMovieMetadata("爱丽丝梦游仙境", "美国", "奇幻,冒险");
        addMovieMetadata("哈利波特与死亡圣器（下）", "美国", "奇幻,冒险");
        addMovieMetadata("星球大战：最后的绝地武士", "美国", "动作,科幻,冒险");
        addMovieMetadata("速度与激情8", "美国", "动作,犯罪,冒险");
        addMovieMetadata("黑豹2", "美国", "动作,科幻,冒险");
        addMovieMetadata("毒液：致命守护者", "美国", "动作,科幻,惊悚");
        addMovieMetadata("蚁人2：黄蜂女现身", "美国", "动作,科幻,冒险");
        addMovieMetadata("美国队长2", "美国", "动作,科幻,冒险");
        addMovieMetadata("雷神2：黑暗世界", "美国", "动作,科幻,奇幻");
        addMovieMetadata("钢铁侠2", "美国", "动作,科幻,冒险");
        addMovieMetadata("哈利波特与火焰杯", "美国", "奇幻,冒险");
        addMovieMetadata("变形金刚", "美国", "动作,科幻,冒险");
        addMovieMetadata("独立日", "美国", "动作,科幻,冒险");
        addMovieMetadata("侏罗纪世界2", "美国", "动作,科幻,冒险");
        addMovieMetadata("蜘蛛侠3", "美国", "动作,科幻,冒险");
        addMovieMetadata("哈利波特与凤凰社", "美国", "奇幻,冒险");

        // 中国电影
        addMovieMetadata("哪吒之魔童降世", "中国", "动画,奇幻,冒险");
        addMovieMetadata("流浪地球2", "中国", "科幻,冒险");
        addMovieMetadata("满江红", "中国", "剧情,悬疑,历史");
        addMovieMetadata("长津湖", "中国", "剧情,历史,战争");
        addMovieMetadata("你好，李焕英", "中国", "剧情,喜剧,家庭");
        addMovieMetadata("唐人街探案3", "中国", "喜剧,悬疑,冒险");
        addMovieMetadata("美人鱼", "中国", "喜剧,爱情,奇幻");
        addMovieMetadata("我不是药神", "中国", "剧情,现实,社会");
        addMovieMetadata("红海行动", "中国", "动作,战争,军事");
        addMovieMetadata("战狼2", "中国", "动作,战争,军事");
        addMovieMetadata("封神第一部", "中国", "奇幻,古装,神话");
        addMovieMetadata("独行月球", "中国", "科幻,喜剧,冒险");
        addMovieMetadata("悬崖之上", "中国", "剧情,悬疑,谍战");
        addMovieMetadata("送你一朵小红花", "中国", "剧情,青春,励志");
        addMovieMetadata("少年的你", "中国", "剧情,青春,犯罪");
        addMovieMetadata("我和我的祖国", "中国", "剧情,历史,献礼");
        addMovieMetadata("八佰", "中国", "剧情,历史,战争");
        addMovieMetadata("白蛇：缘起", "中国", "动画,奇幻,爱情");
        addMovieMetadata("误杀", "中国", "剧情,悬疑,犯罪");
        addMovieMetadata("刺杀小说家", "中国", "奇幻,冒险,动作");
    }

    private static void addMovieMetadata(String name, String country, String genre) {
        MOVIE_METADATA.put(name, new MovieMetadata(country, genre));
    }

    private static void insertDataToDatabase(List<MovieInfoCombinedData> dataList) throws SQLException {
        String sql = "INSERT INTO movie_info_combined (movie_id, movie_name, original_language, subtitle_languages, dubbed_languages, target_audience, secondary_audience, created_at, updated_at) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";

        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            conn.setAutoCommit(false);

            for (MovieInfoCombinedData data : dataList) {
                pstmt.setInt(1, data.getMovieId());
                pstmt.setString(2, data.getMovieName());
                pstmt.setString(3, data.getOriginalLanguage());
                pstmt.setString(4, data.getSubtitleLanguages());
                pstmt.setString(5, data.getDubbedLanguages());
                pstmt.setString(6, data.getTargetAudience());
                pstmt.setString(7, data.getSecondaryAudience());

                Timestamp now = new Timestamp(System.currentTimeMillis());
                pstmt.setTimestamp(8, now);
                pstmt.setTimestamp(9, now);

                pstmt.addBatch();

                if ((dataList.indexOf(data) + 1) % BATCH_SIZE == 0) {
                    pstmt.executeBatch();
                }
            }

            pstmt.executeBatch();
            conn.commit();

            log.info("成功插入 {} 条电影数据到数据库", dataList.size());
        } catch (SQLException e) {
            log.error("插入数据到数据库失败", e);
            throw e;
        }
    }

    /**
     * 电影数据模型
     */
    public static class MovieInfoCombinedData {
        private int movieId;
        private String movieName;
        private String originalLanguage;
        private String subtitleLanguages;
        private String dubbedLanguages;
        private String targetAudience;
        private String secondaryAudience;

        public int getMovieId() {
            return movieId;
        }

        public void setMovieId(int movieId) {
            this.movieId = movieId;
        }

        public String getMovieName() {
            return movieName;
        }

        public void setMovieName(String movieName) {
            this.movieName = movieName;
        }

        public String getOriginalLanguage() {
            return originalLanguage;
        }

        public void setOriginalLanguage(String originalLanguage) {
            this.originalLanguage = originalLanguage;
        }

        public String getSubtitleLanguages() {
            return subtitleLanguages;
        }

        public void setSubtitleLanguages(String subtitleLanguages) {
            this.subtitleLanguages = subtitleLanguages;
        }

        public String getDubbedLanguages() {
            return dubbedLanguages;
        }

        public void setDubbedLanguages(String dubbedLanguages) {
            this.dubbedLanguages = dubbedLanguages;
        }

        public String getTargetAudience() {
            return targetAudience;
        }

        public void setTargetAudience(String targetAudience) {
            this.targetAudience = targetAudience;
        }

        public String getSecondaryAudience() {
            return secondaryAudience;
        }

        public void setSecondaryAudience(String secondaryAudience) {
            this.secondaryAudience = secondaryAudience;
        }
    }

    /**
     * 电影元数据模型
     */
    private static class MovieMetadata {
        String country;
        String genre;

        public MovieMetadata(String country, String genre) {
            this.country = country;
            this.genre = genre;
        }
    }
}